<template>
  <div class="codeContainer">
    <div class="flex flex-column justify-content-center">
      <Splitter class="h-25rem">
        <SplitterPanel :size="33" :minSize="10" class="p-2 surface-800">
          <Fieldset legend="HTML" class="h-full">
            <HtmlCoder ref="htmlRef" />
          </Fieldset>
        </SplitterPanel>
        <SplitterPanel :size="33" class="p-2 surface-800">
          <Fieldset legend="JavaScript" class="h-full">
            <JsCoder ref="jsRef" />
          </Fieldset>
        </SplitterPanel>
        <SplitterPanel :size="33" class="p-2 surface-800">
          <Fieldset legend="CSS" class="h-full">
            <CssCoder ref="cssRef" />
          </Fieldset>
        </SplitterPanel>
      </Splitter>
      <Button class="m-3" label="运行" @click="runCode" />
    </div>
    <div id="iframeBox" class="h-20rem bg-white"></div>
  </div>
</template>

<script setup lang="ts">
import { Splitter, SplitterPanel, Fieldset, Button } from '@/utils/primevue'
import HtmlCoder from './components/HtmlCoder.vue'
import CssCoder from './components/CssCoder.vue'
import JsCoder from './components/JsCoder.vue'
import { ref, type IframeHTMLAttributes } from 'vue';

import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'

self.MonacoEnvironment = {
  getWorker(_, label) {
    if (label === 'json') {
      return new jsonWorker()
    }
    if (label === 'css' || label === 'scss' || label === 'less') {
      return new cssWorker()
    }
    if (label === 'html' || label === 'handlebars' || label === 'razor') {
      return new htmlWorker()
    }
    if (label === 'typescript' || label === 'javascript') {
      return new tsWorker()
    }
    return new editorWorker()
  }
}

const htmlRef = ref()
const cssRef = ref()
const jsRef = ref()

const codeContent = () => {
  const htmlContent = htmlRef.value.html
  const cssContent = cssRef.value.css
  const jsContent = jsRef.value.js
  let content = `
  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>html</title>
    <style>
      ${cssContent}
    </style>
  </head>
  <body>
    ${htmlContent}
    <script>
      ${jsContent}
    <\/script>
  </body>
  </html>
  `
  return content
}
const runCode = () => {
  const divEl = document.getElementById('iframeBox') as HTMLDivElement
  divEl.firstChild && divEl.removeChild(divEl.firstChild)
  const iframe: HTMLIFrameElement = document.createElement('iframe')
  iframe.width = '100%'
  iframe.height = '100%'
  iframe.frameBorder = '0'
  // 使用 document.createElement 创建的 iframe 元素默认是没有 contentWindow 的。
  // contentWindow 属性是是一个只读属性，用于获取 iframe 元素的窗口对象。但是在创建 iframe 元素后，
  // 需要将其附加到文档中，然后等待 iframe 加载完成后，才能通过 contentWindow 属性来访问它的窗口对象。
  iframe.onload = function () {
    // 访问 iframe 的窗口对象
    var container = iframe?.contentWindow?.document;
    if (container) {
      var s = codeContent()
      container.open()
      container.write(s);
      container.close();
    }
  };
  divEl.appendChild(iframe)
}
</script>

<style lang="scss" scoped>
.codeContainer {
  :deep(.p-fieldset-content) {
    padding: 0;
  }
}
</style>
